﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;


namespace TP_EDA_5847
{
    class Program
    {
        public static List<No> nos;
        public static Dictionary<int, int> points = new Dictionary<int, int>();

        /// <summary>
        /// Main Method, Runs all the Interface and program
        /// </summary>
        static void Main()
        {
            Stopwatch sw = new Stopwatch();
            nos = new List<No>();
            KDTree arv = new KDTree();
            Random rand = new Random();
            string selected = "";
            while (!selected.Equals("exit") && !selected.Equals("Exit"))
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("KD Tree Algoritm! (EDA Assignment - Date:. 18-06-2012");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("1 - Build a random tree");
                Console.WriteLine("2 - Build a Tree, with your points");
                Console.WriteLine("3 - Insert a point");
                Console.WriteLine("4 - Search a ponit on tree");
                Console.WriteLine("5 - Delete a Point on tree");
                Console.WriteLine("6 - Search for the best Neighbour");
                Console.WriteLine("7 - Test the algorithm!");
                Console.WriteLine("exit - Exit application");
                Console.WriteLine("ATENTION : Every option have a graph!");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("Select The Option: ");
                Console.ForegroundColor = ConsoleColor.White;
                selected = Console.ReadLine();
                switch (selected)
                {
                    case "1":
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("How many elements? : ");
                        Console.ForegroundColor = ConsoleColor.White;
                        int nElements = Convert.ToInt32(Console.ReadLine());
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("Min Value : ");
                        Console.ForegroundColor = ConsoleColor.White;
                        int min = Convert.ToInt32(Console.ReadLine());
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("Max value : ");
                        Console.ForegroundColor = ConsoleColor.White;
                        int max = Convert.ToInt32(Console.ReadLine());
                        Console.WriteLine("Building Tree...");
                        sw.Start();
                        for (int i = 0; i < nElements; i++)
                        {
                            nos.Add(new No(new List<int> { rand.Next(min, max), rand.Next(min, max) }));
                        }
                        arv = new KDTree();
                        nos = arv.sortListNos(nos);
                        foreach (No no in nos)
                        {
                            arv.insert(no);
                        }
                        sw.Stop();
                        foreach (No no in nos)
                        {
                            Console.WriteLine(no.toString());
                        }
                        Console.ForegroundColor = ConsoleColor.DarkRed;
                        Console.WriteLine("\nDone! In: " + sw.Elapsed + "\n");
                        Console.ForegroundColor = ConsoleColor.White;
                        Graph g = new Graph("Point Graph", 0);
                        g.ShowDialog();
                        break;
                    case "2":
                        nElements = 1;
                        int xPoint, yPoint;
                        string str = "";
                        nos = new List<No>();
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\n!ATENTION : Type 'exit' to terminate");
                        while (!str.Equals("exit"))
                        {
                            try
                            {
                                Console.ForegroundColor = ConsoleColor.Cyan;
                                Console.Write(nElements + "º ponto x: ");
                                Console.ForegroundColor = ConsoleColor.White;
                                str = Console.ReadLine();
                                xPoint = Convert.ToInt32(str);
                                Console.ForegroundColor = ConsoleColor.Cyan;
                                Console.Write("         y: ");
                                Console.ForegroundColor = ConsoleColor.White;
                                str = Console.ReadLine();
                                yPoint = Convert.ToInt32(str);
                                nElements++;
                                nos.Add(new No(new List<int> { xPoint, yPoint }));
                            }
                            catch
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine("!ATENTION : Cant have Words!\n");
                                Console.ForegroundColor = ConsoleColor.White;
                            }
                        }
                        arv = new KDTree();
                        nos = arv.sortListNos(nos);
                        foreach (No no in nos)
                        {
                            arv.insert(no);
                        }

                        foreach (No no in nos)
                        {
                            Console.WriteLine(no.toString());
                        }

                        Graph g3 = new Graph("Point Graph", 0);
                        g3.ShowDialog();
                        break;
                    case "3":
                        if (arv.root != null)
                        {
                            while (true)
                            {
                                try
                                {
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Insert the point on Tree. \nx: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    xPoint = Convert.ToInt32(Console.ReadLine());
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("y: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    yPoint = Convert.ToInt32(Console.ReadLine());
                                    nos.Add(new No(new List<int> { xPoint, yPoint }));
                                    nos = arv.sortListNos(nos);
                                    arv = new KDTree();
                                    foreach (No no in nos)
                                    {
                                        no.clean();
                                        arv.insert(no);
                                    }

                                    foreach (No no in nos)
                                    {
                                        Console.WriteLine(no.toString());
                                    }
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("\nAnother point?[y/n]:");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    if (Console.ReadLine().Equals("n"))
                                    {
                                        Graph g4 = new Graph("Point Graph", 0);
                                        g4.ShowDialog();
                                        break;
                                    }
                                }
                                catch
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("!ATENTION : Cant have Words!\n");
                                    Console.ForegroundColor = ConsoleColor.White;
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine("Cant do nothing with a empty Tree...\n");
                        }
                        break;
                    case "4":
                        if (arv.root != null)
                        {
                            while (true)
                            {
                                try
                                {
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Insert the point to search on Tree. \nx: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    xPoint = Convert.ToInt32(Console.ReadLine());
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("y: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    yPoint = Convert.ToInt32(Console.ReadLine());
                                    if (arv.search(new No(new List<int> { xPoint, yPoint })).value != null)
                                    {
                                        Console.WriteLine("\nFounded!");
                                        Console.WriteLine(arv.search(new No(new List<int> { xPoint, yPoint })).toString() + "\n");
                                    }
                                    else
                                    {
                                        Console.ForegroundColor = ConsoleColor.Red;
                                        Console.WriteLine("\nNot Found!\n");
                                    }
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Another point?[y/n]:");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    if (Console.ReadLine().Equals("n"))
                                    {
                                        break;
                                    }
                                }
                                catch
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("!ATENTION : Cant have Words!\n");
                                    Console.ForegroundColor = ConsoleColor.White;
                                }
                            }

                        }
                        else
                        {
                            Console.WriteLine("Cant do nothing with a empty Tree...\n");
                        }
                        break;
                    case "5":
                        if (arv.root != null)
                        {
                            while (true)
                            {
                                try
                                {
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Insert the point to search on Tree. \nx: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    xPoint = Convert.ToInt32(Console.ReadLine());
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("y: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    yPoint = Convert.ToInt32(Console.ReadLine());
                                    if (arv.search(new No(new List<int> { xPoint, yPoint })).value != null)
                                    {
                                        nos = arv.remove(nos, arv.search(new No(new List<int> { xPoint, yPoint })));
                                        foreach (No no in nos)
                                        {
                                            Console.WriteLine(no.toString());
                                        }
                                        Console.WriteLine("\nDone!\n");
                                    }
                                    else
                                    {
                                        Console.WriteLine("\nThat point on tree dont exists!\n");
                                    }
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Another point?[y/n]:");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    if (Console.ReadLine().Equals("n"))
                                    {
                                        break;
                                    }
                                }
                                catch
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("!ATENTION : Cant have Words!\n");
                                    Console.ForegroundColor = ConsoleColor.White;
                                }
                            }

                        }
                        else
                        {
                            Console.WriteLine("Cant do nothing with a empty Tree...\n");
                        }
                        break;
                    case "6":
                        if (arv.root != null)
                        {
                            while (true)
                            {
                                try
                                {
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Point, to calculate the closest point on tree. \nx: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    xPoint = Convert.ToInt32(Console.ReadLine());
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("y: ");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    yPoint = Convert.ToInt32(Console.ReadLine());

                                    No closestPoint = arv.NearestNeighBour(new List<int> { xPoint, yPoint });
                                    Console.Write("\n" + closestPoint.toString() + "\n\n");

                                    Graph g6 = new Graph("Point Graph", 0);
                                    g6.addPoint(new List<int> { xPoint, yPoint }, closestPoint.value);
                                    g6.ShowDialog();

                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    Console.Write("Another point?[y/n]:");
                                    Console.ForegroundColor = ConsoleColor.White;
                                    if (Console.ReadLine().Equals("n"))
                                    {
                                        break;
                                    }
                                }
                                catch
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("!ATENTION : Cant have Words!\n");
                                    Console.ForegroundColor = ConsoleColor.White;
                                }
                            }

                        }
                        else
                        {
                            Console.WriteLine("Cant do nothing with a empty Tree...\n");
                        }
                        break;
                    case "7":
                        Console.WriteLine("Wait Please... While program is Working!");
                        nElements = 10000;
                        double state = 0;
                        string stateLabel = "";
                        for (int x = 0; x < 30; x++)
                        {
                            sw.Reset();
                            sw.Start();
                            KDTree arvTest = new KDTree();
                            List<No> nosTest = new List<No>();
                            for (int i = 0; i < nElements; i++)
                            {
                                nosTest.Add(new No(new List<int> { rand.Next(0, 1000), rand.Next(0, 1000) }));
                            }
                            nosTest = arvTest.sortListNos(nosTest);
                            foreach (No no in nosTest)
                            {
                                arvTest.insert(no);
                            }
                            sw.Stop();
                            state += 3.3333333;
                            stateLabel += "||";
                            Console.Clear();
                            Console.Write("Wait Please... While program is Working!\n\n" + stateLabel + "  " + Convert.ToInt32(state) + "%\n");
                            points.Add(nElements, (sw.Elapsed.Seconds * 1000) + sw.Elapsed.Milliseconds);
                            nElements += 10000;
                        }
                        Console.WriteLine("\nThank You! Now you have your graph!");
                        Graph g2 = new Graph("Test Graph", 1);
                        g2.ShowDialog();
                        break;
                    default:
                        Console.WriteLine("selecao invalida!");
                        break;
                }
            }
        }
    }
}
